#ifndef XMPPIMPL_H
#define XMPPIMPL_H

#include "xmpp.h"

#include <gloox/messagehandler.h>
#include <gloox/presencehandler.h>
#include <gloox/connectionlistener.h>
#include <gloox/rosterlistener.h>
#include <gloox/rostermanager.h>
#include <gloox/vcardhandler.h>
#include <gloox/error.h>
#include <gloox/vcardmanager.h>
#include <gloox/mutex.h>
#include <gloox/client.h>
#include <gloox/pubsubmanager.h>
#include <gloox/messagesessionhandler.h>
#include <gloox/messagesession.h>

#if defined (WIN32)
#include <memory>
#else
#include <tr1/memory>
#endif
class XmppImpl:public Xmpp, public gloox::PresenceHandler, gloox::ConnectionListener, gloox::VCardHandler, gloox::RosterListener, gloox::MessageSessionHandler
{
public:
    static Xmpp& instance();
    void setDelegate(XmppEventHandler * pDelegate)
    {
        m_delegateMutex.lock();
        m_pDelegate = pDelegate;
        m_delegateMutex.unlock();
    }
    bool setLoginInfo(std::string loginId, std::string password);
    void connect();
    void disconnect();
    bool isConnected();
    void requestVcard(std::string jid);
    gloox::MessageSession* startChat(std::string& jid);
    void closeSession(gloox::MessageSession* pSession);

protected:
//    virtual void handleMessage( const gloox::Message& stanza,
//                               gloox::MessageSession* session = 0 );
    virtual void 	handlePresence (const gloox::Presence &presence);
    virtual void 	onConnect ();
    virtual void 	onDisconnect (gloox::ConnectionError e);
    virtual void 	onSessionCreateError (const gloox::Error *error);
    virtual bool 	onTLSConnect (const gloox::CertInfo &info);
    //    virtual void 	onResourceBind (const std::string &resource)
    //    virtual void 	onResourceBindError (const Error *error)
//    virtual void 	onStreamEvent (StreamEvent event)
    virtual void 	handleVCard (const gloox::JID &jid, const gloox::VCard *vcard);
    virtual void 	handleVCardResult (gloox::VCardHandler::VCardContext context, const gloox::JID &jid, gloox::StanzaError se=gloox::StanzaErrorUndefined);


    virtual void 	handleItemAdded (const gloox::JID &jid){}
    virtual void 	handleItemSubscribed (const gloox::JID &jid){}
    virtual void 	handleItemRemoved (const gloox::JID &jid){}
    virtual void 	handleItemUpdated (const gloox::JID &jid){}
    virtual void 	handleItemUnsubscribed (const gloox::JID &jid){}
    virtual void 	handleRoster (const gloox::Roster &roster);
    virtual void 	handleRosterPresence (const gloox::RosterItem &item, const std::string &resource, gloox::Presence::PresenceType presence, const std::string &msg){}
    virtual void 	handleSelfPresence (const gloox::RosterItem &item, const std::string &resource, gloox::Presence::PresenceType presence, const std::string &msg){}
    virtual bool 	handleSubscriptionRequest (const gloox::JID &jid, const std::string &msg){return false;}
    virtual bool 	handleUnsubscriptionRequest (const gloox::JID &jid, const std::string &msg){return false;}
    virtual void 	handleNonrosterPresence (const gloox::Presence &presence);
    virtual void 	handleRosterError (const gloox::IQ &iq);
    virtual void 	handleMessageSession (gloox::MessageSession *session);

private:
    XmppImpl();
    virtual ~XmppImpl();
    std::tr1::shared_ptr<gloox::Client> m_pClient;
    std::tr1::shared_ptr<gloox::PubSub::Manager> m_pPubSubManager;
    std::tr1::shared_ptr<gloox::VCardManager> m_pVcardManager;
    gloox::RosterManager* m_pRosterManager;
    XmppEventHandler* m_pDelegate;
    gloox::util::Mutex  m_delegateMutex;


};

#endif // XMPPIMPL_H
